<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>📸 图片上传测试器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        .upload-section {
            padding: 40px;
            text-align: center;
        }
        
        .upload-area {
            border: 4px dashed #667eea;
            border-radius: 15px;
            padding: 60px 40px;
            margin: 20px 0;
            background: #f8f9ff;
            transition: all 0.3s ease;
            cursor: pointer;
            position: relative;
        }
        
        .upload-area:hover, .upload-area.dragover {
            border-color: #764ba2;
            background: #f0f2ff;
            transform: translateY(-2px);
            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
        }
        
        .upload-icon {
            font-size: 5em;
            color: #667eea;
            margin-bottom: 20px;
        }
        
        .upload-text {
            font-size: 1.3em;
            color: #333;
            margin-bottom: 10px;
        }
        
        .upload-hint {
            color: #666;
            font-size: 1em;
        }
        
        .file-input {
            display: none;
        }
        
        .btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 25px;
            font-size: 1.1em;
            cursor: pointer;
            transition: all 0.3s ease;
            margin: 10px;
            box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
        }
        
        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4);
        }
        
        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }
        
        .progress-container {
            margin: 30px 0;
            display: none;
        }
        
        .progress-bar {
            height: 30px;
            background: #e0e0e0;
            border-radius: 15px;
            overflow: hidden;
            position: relative;
        }
        
        .progress-fill {
            height: 100%;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 15px;
            transition: width 0.3s ease;
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
        }
        
        .preview-section {
            padding: 20px;
            background: #f8f9fa;
            border-radius: 15px;
            margin: 20px 0;
            display: none;
        }
        
        .preview-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
            gap: 15px;
            margin-top: 20px;
        }
        
        .preview-item {
            background: white;
            border-radius: 10px;
            padding: 10px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
            text-align: center;
        }
        
        .preview-item img {
            width: 100%;
            height: 120px;
            object-fit: cover;
            border-radius: 8px;
            margin-bottom: 10px;
        }
        
        .preview-item-info {
            font-size: 0.9em;
            color: #666;
        }
        
        .gallery-section {
            padding: 40px;
            background: #f8f9fa;
        }
        
        .gallery-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 20px;
        }
        
        .gallery-item {
            background: white;
            border-radius: 15px;
            overflow: hidden;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            transition: all 0.3s ease;
        }
        
        .gallery-item:hover {
            transform: translateY(-5px);
            box-shadow: 0 15px 40px rgba(0,0,0,0.15);
        }
        
        .gallery-item img {
            width: 100%;
            height: 200px;
            object-fit: cover;
        }
        
        .gallery-item-info {
            padding: 15px;
        }
        
        .gallery-item-name {
            font-weight: bold;
            margin-bottom: 5px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        
        .gallery-item-size {
            color: #666;
            font-size: 0.9em;
        }
        
        .status-message {
            padding: 15px;
            border-radius: 10px;
            margin: 20px 0;
            text-align: center;
            font-weight: bold;
        }
        
        .status-success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        
        .status-error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        
        .status-info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }
        
        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #666;
        }
        
        .empty-state-icon {
            font-size: 4em;
            margin-bottom: 20px;
            opacity: 0.5;
        }
        
        .stats {
            display: flex;
            justify-content: space-around;
            background: white;
            padding: 20px;
            border-radius: 15px;
            margin: 20px 0;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
        }
        
        .stat-item {
            text-align: center;
        }
        
        .stat-number {
            font-size: 2em;
            font-weight: bold;
            color: #667eea;
        }
        
        .stat-label {
            color: #666;
            font-size: 0.9em;
        }
        
        @media (max-width: 768px) {
            .container {
                margin: 10px;
                border-radius: 15px;
            }
            
            .upload-area {
                padding: 40px 20px;
            }
            
            .gallery-grid {
                grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
                gap: 15px;
            }
            
            .stats {
                flex-direction: column;
                gap: 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📸 图片上传测试器</h1>
            <p>支持本地存储和实时预览的图片管理系统</p>
        </div>
        
        <div class="upload-section">
            <div class="upload-area" id="uploadArea">
                <div class="upload-icon">☁️</div>
                <div class="upload-text">点击选择图片或拖拽图片到此处</div>
                <div class="upload-hint">支持 JPG、PNG、GIF、WEBP 格式</div>
                <input type="file" id="fileInput" class="file-input" accept="image/*" multiple>
            </div>
            
            <div>
                <button class="btn" onclick="selectFiles()">📁 选择文件</button>
                <button class="btn" onclick="uploadImages()">📤 开始上传</button>
                <button class="btn" onclick="clearAllImages()">🗑️ 清空所有</button>
                <button class="btn" onclick="loadStoredImages()">🔄 刷新图库</button>
            </div>
            
            <div class="progress-container" id="progressContainer">
                <div class="progress-bar">
                    <div class="progress-fill" id="progressFill">0%</div>
                </div>
            </div>
            
            <div id="statusMessage"></div>
            
            <div class="preview-section" id="previewSection">
                <h3>📋 预览选择的图片</h3>
                <div class="preview-grid" id="previewGrid"></div>
            </div>
        </div>
        
        <div class="gallery-section">
            <h2>🖼️ 图片库</h2>
            <div class="stats" id="statsContainer" style="display: none;">
                <div class="stat-item">
                    <div class="stat-number" id="totalImages">0</div>
                    <div class="stat-label">总图片数</div>
                </div>
                <div class="stat-item">
                    <div class="stat-number" id="totalSize">0 MB</div>
                    <div class="stat-label">总大小</div>
                </div>
                <div class="stat-item">
                    <div class="stat-number" id="uploadDate">-</div>
                    <div class="stat-label">最后上传</div>
                </div>
            </div>
            
            <div id="galleryContainer">
                <div class="empty-state" id="emptyState">
                    <div class="empty-state-icon">🖼️</div>
                    <h3>还没有图片</h3>
                    <p>点击上方上传区域添加您的第一张图片</p>
                </div>
                <div class="gallery-grid" id="galleryGrid"></div>
            </div>
        </div>
    </div>

    <script>
        class ImageManager {
            constructor() {
                this.selectedFiles = [];
                this.storedImages = [];
                this.storageKey = 'uploadedImages_v2';
                this.init();
            }
            
            init() {
                this.setupEventListeners();
                this.loadStoredImages();
            }
            
            setupEventListeners() {
                const uploadArea = document.getElementById('uploadArea');
                const fileInput = document.getElementById('fileInput');
                
                // 点击上传
                uploadArea.addEventListener('click', () => fileInput.click());
                
                // 文件选择
                fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
                
                // 拖拽功能
                uploadArea.addEventListener('dragover', (e) => {
                    e.preventDefault();
                    uploadArea.classList.add('dragover');
                });
                
                uploadArea.addEventListener('dragleave', () => {
                    uploadArea.classList.remove('dragover');
                });
                
                uploadArea.addEventListener('drop', (e) => {
                    e.preventDefault();
                    uploadArea.classList.remove('dragover');
                    const files = Array.from(e.dataTransfer.files);
                    this.processFiles(files);
                });
            }
            
            handleFileSelect(event) {
                const files = Array.from(event.target.files);
                this.processFiles(files);
            }
            
            processFiles(files) {
                const imageFiles = files.filter(file => 
                    file.type.startsWith('image/') && file.size <= 10 * 1024 * 1024
                );
                
                if (imageFiles.length === 0) {
                    this.showMessage('请选择有效的图片文件（最大10MB）', 'error');
                    return;
                }
                
                this.selectedFiles = imageFiles;
                this.displayPreview();
                this.showMessage(`已选择 ${imageFiles.length} 张图片`, 'success');
            }
            
            displayPreview() {
                const previewSection = document.getElementById('previewSection');
                const previewGrid = document.getElementById('previewGrid');
                
                if (this.selectedFiles.length === 0) {
                    previewSection.style.display = 'none';
                    return;
                }
                
                previewSection.style.display = 'block';
                previewGrid.innerHTML = '';
                
                this.selectedFiles.forEach((file, index) => {
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        const previewItem = document.createElement('div');
                        previewItem.className = 'preview-item';
                        previewItem.innerHTML = `
                            <img src="${e.target.result}" alt="${file.name}">
                            <div class="preview-item-info">
                                <div>${file.name}</div>
                                <div>${this.formatFileSize(file.size)}</div>
                            </div>
                        `;
                        previewGrid.appendChild(previewItem);
                    };
                    reader.readAsDataURL(file);
                });
            }
            
            uploadImages() {
                if (this.selectedFiles.length === 0) {
                    this.showMessage('请先选择图片文件', 'error');
                    return;
                }
                
                this.showProgress(true);
                this.simulateUpload();
            }
            
            simulateUpload() {
                const total = this.selectedFiles.length;
                let uploaded = 0;
                
                const uploadNext = () => {
                    if (uploaded >= total) {
                        this.showProgress(false);
                        this.showMessage(`成功上传 ${total} 张图片！`, 'success');
                        this.saveImagesToStorage();
                        this.selectedFiles = [];
                        document.getElementById('previewSection').style.display = 'none';
                        document.getElementById('fileInput').value = '';
                        return;
                    }
                    
                    const file = this.selectedFiles[uploaded];
                    this.saveImageToStorage(file, () => {
                        uploaded++;
                        this.updateProgress((uploaded / total) * 100);
                        setTimeout(uploadNext, 300);
                    });
                };
                
                uploadNext();
            }
            
            saveImageToStorage(file, callback) {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const imageData = {
                        id: Date.now() + Math.random(),
                        name: file.name,
                        data: e.target.result,
                        size: file.size,
                        type: file.type,
                        uploadTime: new Date().toISOString(),
                        width: 0,
                        height: 0
                    };
                    
                    // 获取图片尺寸
                    const img = new Image();
                    img.onload = () => {
                        imageData.width = img.width;
                        imageData.height = img.height;
                        this.storedImages.unshift(imageData);
                        callback();
                    };
                    img.src = e.target.result;
                };
                reader.readAsDataURL(file);
            }
            
            saveImagesToStorage() {
                localStorage.setItem(this.storageKey, JSON.stringify(this.storedImages));
                this.loadStoredImages();
            }
            
            loadStoredImages() {
                try {
                    const stored = localStorage.getItem(this.storageKey);
                    this.storedImages = stored ? JSON.parse(stored) : [];
                    this.displayGallery();
                    this.updateStats();
                } catch (error) {
                    console.error('加载图片失败:', error);
                    this.storedImages = [];
                }
            }
            
            displayGallery() {
                const galleryGrid = document.getElementById('galleryGrid');
                const emptyState = document.getElementById('emptyState');
                
                if (this.storedImages.length === 0) {
                    galleryGrid.innerHTML = '';
                    emptyState.style.display = 'block';
                    return;
                }
                
                emptyState.style.display = 'none';
                
                galleryGrid.innerHTML = this.storedImages.map(image => `
                    <div class="gallery-item">
                        <img src="${image.data}" alt="${image.name}" 
                             onclick="imageManager.viewImage('${image.id}')"
                             style="cursor: pointer;">
                        <div class="gallery-item-info">
                            <div class="gallery-item-name" title="${image.name}">${image.name}</div>
                            <div class="gallery-item-size">
                                ${this.formatFileSize(image.size)} • ${image.width}×${image.height}
                            </div>
                            <div style="margin-top: 10px;">
                                <button class="btn" style="padding: 8px 15px; font-size: 0.9em;" 
                                        onclick="imageManager.viewImage('${image.id}')">👁️ 查看</button>
                                <button class="btn" style="padding: 8px 15px; font-size: 0.9em; background: #dc3545;" 
                                        onclick="imageManager.deleteImage('${image.id}')">🗑️ 删除</button>
                            </div>
                        </div>
                    </div>
                `).join('');
            }
            
            viewImage(imageId) {
                const image = this.storedImages.find(img => img.id == imageId);
                if (!image) return;
                
                const modal = document.createElement('div');
                modal.style.cssText = `
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    background: rgba(0,0,0,0.9);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    z-index: 1000;
                    cursor: pointer;
                `;
                
                modal.innerHTML = `
                    <div style="max-width: 90%; max-height: 90%; text-align: center;">
                        <img src="${image.data}" alt="${image.name}" 
                             style="max-width: 100%; max-height: 80vh; border-radius: 10px;">
                        <div style="color: white; margin-top: 20px; font-size: 1.2em;">
                            ${image.name} (${this.formatFileSize(image.size)})
                        </div>
                    </div>
                `;
                
                modal.onclick = () => document.body.removeChild(modal);
                document.body.appendChild(modal);
            }
            
            deleteImage(imageId) {
                if (!confirm('确定要删除这张图片吗？')) return;
                
                this.storedImages = this.storedImages.filter(img => img.id != imageId);
                this.saveImagesToStorage();
                this.showMessage('图片删除成功', 'success');
            }
            
            clearAllImages() {
                if (this.storedImages.length === 0) {
                    this.showMessage('图片库已经是空的', 'info');
                    return;
                }
                
                if (confirm(`确定要清空所有 ${this.storedImages.length} 张图片吗？`)) {
                    this.storedImages = [];
                    this.saveImagesToStorage();
                    this.showMessage('图片库已清空', 'success');
                }
            }
            
            updateStats() {
                const statsContainer = document.getElementById('statsContainer');
                const totalImages = document.getElementById('totalImages');
                const totalSize = document.getElementById('totalSize');
                const uploadDate = document.getElementById('uploadDate');
                
                if (this.storedImages.length === 0) {
                    statsContainer.style.display = 'none';
                    return;
                }
                
                const totalBytes = this.storedImages.reduce((sum, img) => sum + img.size, 0);
                const latestUpload = this.storedImages[0]?.uploadTime;
                
                statsContainer.style.display = 'flex';
                totalImages.textContent = this.storedImages.length;
                totalSize.textContent = this.formatFileSize(totalBytes);
                uploadDate.textContent = latestUpload ? new Date(latestUpload).toLocaleDateString() : '-';
            }
            
            showProgress(show) {
                const progressContainer = document.getElementById('progressContainer');
                progressContainer.style.display = show ? 'block' : 'none';
                if (!show) {
                    this.updateProgress(0);
                }
            }
            
            updateProgress(percent) {
                const progressFill = document.getElementById('progressFill');
                progressFill.style.width = percent + '%';
                progressFill.textContent = Math.round(percent) + '%';
            }
            
            showMessage(message, type = 'info') {
                const statusMessage = document.getElementById('statusMessage');
                const className = `status-message status-${type}`;
                statusMessage.className = className;
                statusMessage.textContent = message;
                statusMessage.style.display = 'block';
                
                setTimeout(() => {
                    statusMessage.style.display = 'none';
                }, 3000);
            }
            
            formatFileSize(bytes) {
                if (bytes === 0) return '0 Bytes';
                const k = 1024;
                const sizes = ['Bytes', 'KB', 'MB', 'GB'];
                const i = Math.floor(Math.log(bytes) / Math.log(k));
                return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
            }
        }
        
        // 全局实例
        let imageManager;
        
        // 便捷函数
        function selectFiles() {
            document.getElementById('fileInput').click();
        }
        
        function uploadImages() {
            imageManager.uploadImages();
        }
        
        function clearAllImages() {
            imageManager.clearAllImages();
        }
        
        function loadStoredImages() {
            imageManager.loadStoredImages();
        }
        
        // 初始化
        document.addEventListener('DOMContentLoaded', () => {
            imageManager = new ImageManager();
        });
    </script>
</body>
</html>